package com.badger.generator.base.entity;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import lombok.Getter;
import lombok.Setter;

/**
 * 分页工具类.
 * @author liqi mysql 分页算法
 * @param <E> 泛型类型
 */
@Getter
@Setter
public class PageInfo<E> {
    /** 默认每页15条数据. */
    public static final Integer INIT_SIZE = 15;
    /** 默认当前页为1. */
    public static final Integer INIT_PAGE = 1;
    /** 默认总条数为1万. */
    public static final Integer INIT_COUNT = 10000;
    /** 默认边界值为-1. */
    public static final Integer INIT_OUT = -1;

    /** 每页多少. */
    private Integer pageSize;
    /** 当前起始页. */
    private Integer page;
    /** 总记录数. */
    private Integer count;
    /** 总页数 (尾页页码). */
    private Integer totalPage;
    /** 分页开始记录行. */
    private Integer start;
    /** 分页结束记录行. */
    private Integer end;

    /** 上一页的页码 页码，为-1时候，没有首页，尾页，上一页，或者下一页的页码. */
    private Integer previoustPage;
    /** 下一页的页码，为-1时候，没有首页，尾页，上一页，或者下一页的页码. */
    private Integer nextPage;
    /** 首页页码，为-1时候，没有首页，尾页，上一页，或者下一页的页码. */
    private Integer firstPage;
    /** 尾页页码，为-1时候，没有首页，尾页，上一页，或者下一页的页码. */
    private Integer lastPage;

    /** 泛型的对象：取里面的参数做查询条件. */
    private E e;
    /** 分页数据的list. */
    private List<E> list;
    /** 查询条件，开始时间. */
    private Date startTime;
    /** 查询条件，结束时间. */
    private Date endTime;
    /** 页面存放前段的页数：固定为4个页数，当前页前4个，后5个. */
    private List<Integer> satrtPageList = new ArrayList<Integer>();
    /** 页面存放后段的页数：固定为5个页数，当前页前4个，后5个. */
    private List<Integer> endPageList = new ArrayList<Integer>();

    /**
     * 构造方法.
     * @param pageSize 每页多少条； 默认为15
     * @param page 当前第几页 ；默认为1
     * @param count 总共多少条；默认为10000
     * @param e 实体泛型 ；默认为null
     * @param startTime 查询条件，开始时间；默认为null
     * @param endTime 查询条件，结束时间;默认为null
     */
    public PageInfo(final Integer pageSize, final Integer page, final Integer count, final E e, final Date startTime,
            final Date endTime) {
        init(pageSize, page, count, e, startTime, endTime);
    }

    /**
     * 构造方法.
     * @param pageSize 每页多少条； 默认为15
     * @param page 当前第几页 ；默认为1
     * @param count 总共多少条；默认为10000
     * @param e 实体泛型 ；默认为null
     */
    public PageInfo(final Integer pageSize, final Integer page, final Integer count, final E e) {
        this(pageSize, page, count, e, null, null);
    }

    /**
     * 构造方法.
     * @param pageSize 每页多少条； 默认为15
     * @param page 当前第几页 ；默认为1
     * @param count 总共多少条；默认为10000
     */
    public PageInfo(final Integer pageSize, final Integer page, final Integer count) {
        this(pageSize, page, count, null);
    }

    /**
     * 构造方法.
     * @param page 当前第几页 ；默认为1
     * @param count 总共多少条；默认为10000
     */
    public PageInfo(final Integer page, final Integer count) {
        this(INIT_SIZE, page, count);
    }

    /**
     * 构造方法，job使用，每次查询当前第一页，pageSize数据.
     * @param pageSize 每页多少条； 默认为15
     * @param e 实体泛型 ；默认为null
     * @param startTime 查询条件，开始时间；默认为null
     * @param endTime 查询条件，结束时间;默认为null
     */
    public PageInfo(final Integer pageSize, final E e, final Date startTime, final Date endTime) {
        this(pageSize, INIT_PAGE, INIT_COUNT, e, startTime, endTime);
    }

    private void init(final Integer pageSize, final Integer page, final Integer count, final E e, final Date startTime,
            final Date endTime) {
        if (pageSize != null) {
            this.pageSize = pageSize;
        }
        this.page = page;
        this.count = count;

        if (this.count % this.pageSize == 0) {
            this.totalPage = this.count / this.pageSize;
        } else {
            this.totalPage = this.count / this.pageSize + 1;
        }
        if (this.page == INIT_PAGE) {
            this.start = 0;
            // 当前页数==1 时; 首页不可点击
            this.firstPage = INIT_OUT;
        } else {
            this.start = (this.page - 1) * this.pageSize;
            this.firstPage = INIT_PAGE;
        }

        this.end = this.pageSize;

        if (this.page - 1 > 0) {
            this.previoustPage = this.page - 1;
        } else {
            this.previoustPage = INIT_OUT;
        }
        if (this.page + 1 <= this.totalPage) {
            this.nextPage = this.page + 1;
        } else {
            this.nextPage = INIT_OUT;
        }
        if (this.page == this.totalPage) {
            // 当前页==总页数 时，当前页为最后一页；尾页为-1，不可点击
            this.lastPage = INIT_OUT;
        } else {
            this.lastPage = this.totalPage;
        }
        if (this.totalPage < 11) {
            for (int i = 1; i < this.page; i++) {
                satrtPageList.add(i);
            }
            for (int i = this.page; i < this.totalPage; i++) {
                endPageList.add(i + 1);
            }
        } else {
            // 当前页：前半部分
            if (this.page - 4 > 0) {
                int dd = 4;
                if (this.page + 5 > this.totalPage) {
                    dd = dd + this.page + 5 - this.totalPage;
                }
                for (int i = dd; i > 0; i--) {
                    satrtPageList.add(this.page - i);
                }
            } else {
                for (int i = this.page - 1; i > 0; i--) {
                    satrtPageList.add(this.page - i);
                }
            }
            // 当前页：后半部分
            if (this.page + 5 <= this.totalPage) {
                int dd = 5;
                if (satrtPageList.size() < 5) {
                    dd = dd * 2 - satrtPageList.size();
                    if (this.page + dd > this.totalPage) {
                        dd = this.totalPage - this.page;
                    }
                }
                for (int i = 1; i <= dd; i++) {
                    endPageList.add(this.page + i);
                }
            } else {
                for (int i = 1; i <= (this.totalPage - this.page); i++) {
                    endPageList.add(this.page + i);
                }
            }
        }
        this.e = e;
        this.startTime = startTime;
        this.endTime = endTime;
    }
}
